#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import winxpgui, win32con, win32ui
import time
from dshow import build_graph, MFVideoARMode_PreservePicture
from ctypes.wintypes import tagRECT
from ctypes import *

# DirectShow.
media_control, evr_videocontrol = build_graph()
swp_flags = win32con.SWP_FRAMECHANGED | win32con.SWP_SHOWWINDOW | \
    win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_NOREPOSITION

def go_fullscreen(hwnd):
    evr_videocontrol.SetFullscreen(True)
    winxpgui.DefWindowProc(hwnd, win32con.WM_SYSCOMMAND, \
        win32con.SC_MAXIMIZE, -1)
    winxpgui.SetWindowPos(hwnd, win32con.HWND_TOP, \
        0, 0, 0, 0, swp_flags)

def revert_fullscreen(hwnd):
    evr_videocontrol.SetFullscreen(False)
    winxpgui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, \
        0, 0, 0, 0, swp_flags)
    winxpgui.DefWindowProc(hwnd, win32con.WM_SYSCOMMAND, \
        win32con.SC_RESTORE, -1)

def is_maximized(hwnd):
    pcwnd = win32ui.CreateWindowFromHandle(hwnd)
    return pcwnd.IsZoomed()

def on_close(hwnd, msg, wparam, lparam):
    winxpgui.DestroyWindow(hwnd)

def on_destroy(hwnd, msg, wparam, lparam):
    winxpgui.PostQuitMessage(0)

def on_sys(hwnd, msg, wparam, lparam):
    if wparam == win32con.SC_MAXIMIZE:
        # Send fullscreen
        go_fullscreen(hwnd)
    elif wparam == win32con.SC_MINIMIZE:
        # Pause?
        pass
    elif wparam == win32con.SC_RESTORE:
        # Disable fullscreen
        revert_fullscreen(hwnd)
    elif wparam == win32con.SC_CLOSE:
        # Shutdown
        pass
    elif wparam == win32con.SC_KEYMENU:
        if lparam == ord('\r'):
            if is_maximized(hwnd):
                # Disable fullscreen
                revert_fullscreen(hwnd)
                return winxpgui.DefWindowProc(hwnd, msg, \
                    win32con.SC_RESTORE, -1)
            else:
                # Send Fullscreen
                go_fullscreen(hwnd)
                time.sleep(0.1)
                return winxpgui.DefWindowProc(hwnd, msg, \
                    win32con.SC_MAXIMIZE, -1)
    #print("message: %d" % msg, "wparam: %d" % wparam, "lparam: %d" % lparam)
    return winxpgui.DefWindowProc(hwnd, msg, wparam, lparam)

def on_keyup(hwnd, msg, wparam, lparam):
    if wparam == 27: # Esc
        if is_maximized(hwnd):
            # Disable Fullscreen
            revert_fullscreen(hwnd)
            return winxpgui.DefWindowProc(hwnd, win32con.WM_SYSCOMMAND, \
                    win32con.SC_RESTORE, -1)
    return winxpgui.DefWindowProc(hwnd, msg, wparam, lparam)

def on_sizing(hwnd, msg, wparam, lparam):
    newsize = cast(lparam, POINTER(tagRECT))
    width = newsize[0].right - newsize[0].left
    height = newsize[0].bottom - newsize[0].top
    newsize = tagRECT(0,0,width,height)
    evr_videocontrol.SetVideoPosition(None, newsize)

wndproc = { 
    win32con.WM_CLOSE:on_close,
    win32con.WM_SYSCOMMAND:on_sys,
    win32con.WM_KEYUP:on_keyup,
    win32con.WM_DESTROY:on_destroy,
    win32con.WM_SIZING:on_sizing,
}

# wc = window class
wc = winxpgui.WNDCLASS()
wc.lpszClassName = "EVR"
wc.style = win32con.CS_GLOBALCLASS|win32con.CS_VREDRAW | win32con.CS_HREDRAW
wc.hbrBackground = win32con.COLOR_BACKGROUND+1
wc.hCursor = winxpgui.LoadCursor(0, win32con.IDC_ARROW)
wc.lpfnWndProc = wndproc
class_atom = winxpgui.RegisterClass(wc)
hwnd = winxpgui.CreateWindow(wc.lpszClassName,
    "Python Video Capture EVR Test",
    win32con.WS_TILEDWINDOW | win32con.WS_VISIBLE,
    100,100,1024,798, 0, 0, 0, None)

## Set EVR window to our window.
evr_videocontrol.SetVideoWindow(hwnd)
evr_videocontrol.SetAspectRatioMode(MFVideoARMode_PreservePicture)
dummyRect = tagRECT(0,0,1024,768)

evr_videocontrol.SetVideoPosition(None, dummyRect)
# Start the graph with mediacontrol.
media_control.Run()

while winxpgui.PumpWaitingMessages() == 0:
    time.sleep(0.3)
    media_control.GetState(6000)